package com.zxy.zxyrpc.springboot.starter.bootstrap;

import com.zxy.zxyrpc.RpcApplication;
import com.zxy.zxyrpc.config.RpcConfig;
import com.zxy.zxyrpc.model.ServiceMetaInfo;
import com.zxy.zxyrpc.registry.LocalRegistry;
import com.zxy.zxyrpc.registry.Registry;
import com.zxy.zxyrpc.registry.RegistryFactory;
import com.zxy.zxyrpc.springboot.starter.annotation.RpcService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

/**
 * RPC 服务提供者启动
 *
 * @author zxy
 * @since 2025/5/30
 **/
@Slf4j
public class RpcProviderBootStrap implements BeanPostProcessor {

    /**
     * Bean 初始化后执行，注册服务
     *
     * @param bean     bean对象
     * @param beanName bean名称
     * @throws BeansException bean创建异常
     */
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        // 获取 bean对象 上的 RpcService注解对象
        Class<?> beanClass = bean.getClass();
        RpcService rpcService = beanClass.getAnnotation(RpcService.class);
        if (rpcService != null) {
            // 获取注册服务信息
            Class<?> interfaceClass = rpcService.interfaceClass();
            // 默认值处理
            if (interfaceClass == void.class)
                // 当前 bean 作为服务提供者
                interfaceClass = beanClass.getInterfaces()[0];
            String serviceName = interfaceClass.getName();
            String serviceVersion = rpcService.serviceVersion();
            // 本地注册
            LocalRegistry.register(serviceName, interfaceClass);
            // 注册中心配置
            final RpcConfig rpcConfig = RpcApplication.getRpcConfig();
            Registry registry = RegistryFactory.getInstance(rpcConfig.getRegistryConfig().getRegistry());
            ServiceMetaInfo serviceMetaInfo = new ServiceMetaInfo();
            serviceMetaInfo.setServiceName(serviceName);
            serviceMetaInfo.setServiceVersion(serviceVersion);
            serviceMetaInfo.setServiceHost(rpcConfig.getServerHost());
            serviceMetaInfo.setServicePort(rpcConfig.getServerPort());

            try {
                registry.registry(serviceMetaInfo);
            } catch (Exception e) {
                throw new RuntimeException("服务注册失败", e);
            }
        }

        return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
    }
}
